#include "h_timer_pwm.h"
#include "h_stm32_hal_defines.h"

#define PWM_TIMER                                 htim3
extern TIM_HandleTypeDef PWM_TIMER;

void h_timer_pwm_start_channel(timer_pwm_channle channel)
{
    switch(channel)
    {
        case pwm_channel_1:
            HAL_TIM_PWM_Start(&PWM_TIMER, TIM_CHANNEL_1);
            break;

        case pwm_channel_2:
            HAL_TIM_PWM_Start(&PWM_TIMER, TIM_CHANNEL_2);
            break;

        case pwm_channel_3:
            HAL_TIM_PWM_Start(&PWM_TIMER, TIM_CHANNEL_3);
            break;

        case pwm_channel_4:
            HAL_TIM_PWM_Start(&PWM_TIMER, TIM_CHANNEL_4);
            break;

        default:
            break;
    }
}

void h_timer_pwm_stop_channel(timer_pwm_channle channel)
{
    switch(channel)
    {
        case pwm_channel_1:
            HAL_TIM_PWM_Stop(&PWM_TIMER, TIM_CHANNEL_1);
            break;

        case pwm_channel_2:
            HAL_TIM_PWM_Stop(&PWM_TIMER, TIM_CHANNEL_2);
            break;

        case pwm_channel_3:
            HAL_TIM_PWM_Stop(&PWM_TIMER, TIM_CHANNEL_3);
            break;

        case pwm_channel_4:
            HAL_TIM_PWM_Stop(&PWM_TIMER, TIM_CHANNEL_4);
            break;

        default:
            break;
    }
}

void h_timer_pwm_change_frq(unsigned int frq)
{
    unsigned int new_main_fep_divide = 0U;

    // new_main_fep_divide = (1024000.0 / frq);
    new_main_fep_divide = (PWM_TIMER.Init.Period * 100.0 / frq);

    /* Set the Autoreload value */
    PWM_TIMER.Instance->ARR = new_main_fep_divide;

    // printf("reload %d, %d\r\n", new_main_fep_divide, PWM_TIMER.Init.Period);

    /* Set the Capture Compare Register value */
    PWM_TIMER.Instance->CCR1 = new_main_fep_divide / 2;
}

void h_timer_pwm_change_channel_duty(timer_pwm_channle channel, unsigned char duty)
{
    duty = (duty > 100)?100:duty;
    // unsigned int new_duty = (1024.0 / duty) - 1;
    unsigned int new_duty = duty * (PWM_TIMER.Instance->ARR / 100);
    switch(channel)
    {
        case pwm_channel_1:
            PWM_TIMER.Instance->CCR1 = new_duty;
            break;

        case pwm_channel_2:
            PWM_TIMER.Instance->CCR2 = new_duty;
            break;

        case pwm_channel_3:
            PWM_TIMER.Instance->CCR3 = new_duty;
            break;

        case pwm_channel_4:
            PWM_TIMER.Instance->CCR4 = new_duty;
            break;

        default:
            break;
    }
}